#nullable disable
namespace Crux.Core.Data;
/// <summary>
/// GenericEntity
/// </summary>
/// <typeparam name="TPrimaryKey"></typeparam>
public abstract class GenericEntity<TPrimaryKey>
    : IGenericEntity<TPrimaryKey>
{
    /// <summary>
    /// 主键
    /// </summary>
    public virtual TPrimaryKey Id { get; set; }
    /// <summary>
    /// 不相等符重载
    /// </summary>
    public static bool operator !=(GenericEntity<TPrimaryKey> left, GenericEntity<TPrimaryKey> right)
    {
        return !(left == right);
    }
    /// <summary>
    /// 相等符重载
    /// </summary>
    public static bool operator ==(GenericEntity<TPrimaryKey> left, GenericEntity<TPrimaryKey> right)
    {
        if (Equals(left, null))
        {
            return Equals(right, null);
        }

        return left.Equals(right);
    }
    /// <summary>
    /// 相等
    /// </summary>
    public override bool Equals(object obj)
    {
        if (obj is null ||
            obj is not IGenericEntity<TPrimaryKey> other)
        {
            return false;
        }

        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        var typeOfThis = base.GetType();
        var typeOfOther = other.GetType();

        if (!typeOfOther.GetTypeInfo().IsAssignableFrom(typeOfThis) &&
            !typeOfThis.GetTypeInfo().IsAssignableFrom(typeOfOther))
        {
            return false;
        }

        return Id.Equals(other.Id);
    }
    /// <summary>
    /// 哈希值
    /// </summary>
    public override int GetHashCode()
        => Id.GetHashCode();
    /// <summary>
    /// 字符串
    /// </summary>
    public override string ToString()
        => $"[Entity {GetType().Name} {Id}]";
    /// <summary>
    /// 解构
    /// </summary>
    /// <param name="id"></param>
    public virtual void Deconstruct(out TPrimaryKey id)
        => id = Id;
}